<?php

namespace App\Foundation;

class EncryptTool
{
    protected $key = null;
    protected $hex_iv = null;

    private $mode = 'AES-128-CBC';

    public function __construct($key = '')
    {
        if (empty($key)) {
            throw new \Exception("缺少加密解密key");
        }

        //如果加密时传入了加密key，则使用新的key进行填充值的计算，否则使用默认的
        if (!empty($key)) {
            //计算生成key
            $this->key = $this->toProductKey($key);

            $this->hex_iv = $this->toProductHexiv($key);
        }
    }

    public function encrypt($input)
    {
        $data = openssl_encrypt($input, $this->mode, $this->key, OPENSSL_RAW_DATA, $this->hex_iv);
        $data = base64_encode($data);
        return $data;
    }


    public function decrypt($input)
    {
        $input = base64_decode($input);
        $decrypted = openssl_decrypt($input, $this->mode, $this->key, OPENSSL_RAW_DATA, $this->hex_iv);
        return $decrypted;
    }


    private function addpadding($string, $blocksize = 16)
    {
        $len = strlen($string);

        $pad = $blocksize - ($len % $blocksize);

        $string .= str_repeat(chr($pad), $pad);

        return $string;
    }

    private function strippadding($string)
    {
        $slast = ord(substr($string, -1));

        $slastc = chr($slast);

        $pcheck = substr($string, -$slast);

        if (preg_match("/$slastc{" . $slast . "}/", $string)) {
            $string = substr($string, 0, strlen($string) - $slast);

            return $string;
        } else {
            return false;
        }
    }

    public function toProductKey($key)
    {
        $keyLength = strlen($key);
        //对传入的key进行md5加密
        $opKey = md5($key);

        $subStart = 0;
        $subEnd = 16;

        if ($keyLength > 16 && $keyLength < 32) {
            $subStart = 32 - $keyLength;
        }

        if ($keyLength < 16) {
            $subStart = $keyLength;
        }

        $prCheck = substr($opKey, $subStart, $subEnd);

        return substr($key.$prCheck, 0, 16);
    }

    public function toProductHexiv($hexIv)
    {
        return substr(md5($hexIv), 0, 16);
    }
}
